#include <iostream>
#include <cstring>

using namespace std;

class myString
{

    friend ostream &operator<<(ostream &cout, const myString &str);
    friend istream &operator>>(istream &cin, myString &str); // TODO

private:
    char *m_p;
    int m_size;

public:
    myString()
    {
        this->m_p = nullptr;
        this->m_size = 0;
    };
    myString(const char *s);
    myString(const myString &str);

    myString operator+(const myString &str);
    myString &operator+=(const myString &str);
    myString &operator=(const char *s);
    myString &operator=(const myString &str);
    char operator[](const int &i);
    bool operator==(const char *str);
    bool operator==(const myString &str);

    ~myString();
};

myString::myString(const char *s) // ok
{
    this->m_size = strlen(s);
    this->m_p = new char[this->m_size];
    strcpy(this->m_p, s);
    // cout << "1234566" <<endl;
}

myString::myString(const myString &str) // ok
{
    this->m_size = str.m_size;
    this->m_p = new char[this->m_size];
    strcpy(this->m_p, str.m_p);
}

myString myString::operator+(const myString &str)
{
    int new_size = strlen(this->m_p) + strlen(str.m_p) + 1;
    char *tmp = new char[new_size];
    // memset(tmp, 0, new_size);
    // strcat(tmp, this->m_p); // this two lines can do the same thing == next line;
    strcpy(tmp, this->m_p);
    strcat(tmp, str.m_p);
    myString tmpStr(tmp);
    delete[] tmp;

    return tmpStr;
}

myString &myString::operator+=(const myString &str)
{
    strcat(this->m_p, str.m_p);
    return *this;
}

myString &myString::operator=(const char *s)
{
    if (this->m_p != nullptr)
    {
        delete[] this->m_p;
        this->m_p = nullptr;
        this->m_size = 0;
    }

    this->m_size = strlen(s);
    this->m_p = new char[strlen(s) + 1];
    strcpy(this->m_p, s);

    return *this;
}

myString &myString::operator=(const myString &str) // ok
{
    if (this->m_p != nullptr)
    {
        delete[] this->m_p;
        this->m_p = nullptr;
        this->m_size = 0;
    }

    this->m_size = strlen(str.m_p);
    this->m_p = new char[strlen(str.m_p) + 1];
    strcpy(this->m_p, str.m_p);

    return *this;
}

char myString::operator[](const int &i)
{
    if (i > this->m_size)
    {
        cerr << "out_of_range!" << endl;
        // return;
    }

    return *(this->m_p + i);
}

bool myString::operator==(const char *str)
{
    if ((strcmp(this->m_p, str) == 0) && (this->m_size == strlen(str)))
    {
        return true;
    }
    return false;
}

bool myString::operator==(const myString &str)
{
    if ((strcmp(this->m_p, str.m_p) == 0) && (this->m_size == str.m_size))
    {
        return true;
    }
    return false;
}

myString::~myString()
{
    if (this->m_p != nullptr)
    {
        delete this->m_p;
        this->m_p = nullptr;
        this->m_size = 0;
        // cout << "8888" <<endl;
    }
}

ostream &operator<<(ostream &cout, const myString &str)
{
    cout << str.m_p;
    return cout;
}

istream &operator>>(istream &cin, myString &str)
{
    if (str.m_p != nullptr)
    {
        delete str.m_p;
        str.m_size = 0;
    }

    char *buf = new char[1024];
    cin >> buf;

    str.m_size = strlen(buf);
    str.m_p = new char[strlen(buf) + 1];
    strcpy(str.m_p, buf);
    delete buf;

    return cin;
}

void test()
{
    myString mst = "abc";

    cout << mst << "--------------" << endl;

    // cin >> mst;
    // cout << mst << "++++++++++++++++" << endl;

    // myString mst1;
    // mst1 = "mst";
    // cout << mst1 << "--------------" << endl;

    myString mst2("abc");
    // myString sum;
    // sum = mst + mst2;
    // // mst2+=mst;
    // cout << "sum = " << sum << endl;

    // cout << sum[2] << endl;

    cout <<(mst2=="abcd") <<endl;
}

int main()
{
    test();
    return 0;
}